<template>
  <a-card :bordered="false">
    <div class="table-page-search-wrapper">
      <a-form ref="queryForm" layout="inline">
        <a-row :gutter="48">
          <a-col :md="6" :sm="18">
            <a-form-item label="任务名称" prop="jobName">
              <a-input
                v-model="queryParams.jobName"
                placeholder="请输入任务名称"
                allowClear
                @keyup.enter.native="handleQuery"
              />
            </a-form-item>
          </a-col>
          <a-col :md="5" :sm="15">
            <a-form-item label="任务组名" prop="jobGroup">
              <a-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" allowClear>
                <a-select-option
                  v-for="dict in jobGroupOptions"
                  :key="dict.dictValue"
                >{{ dict.dictLabel }}</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="5" :sm="15">
            <a-form-item label="任务状态" >
              <a-select v-model="queryParams.status" placeholder="请选择任务状态" >
                <a-select-option
                  v-for="dict in statusOptions"
                  :key="dict.dictValue"
                >{{ dict.dictLabel }}</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :md="4" :sm="12">
            <span class="table-page-search-submitButtons">
              <a-button type="primary" @click="handleQuery">搜索</a-button>
              <a-button style="margin-left: 8px" @click="resetQuery">重置</a-button>
            </span>
          </a-col>
        </a-row>
      </a-form>
    </div>
    <div class="table-operator">
      <a-button type="primary" @click="handleAdd" v-if="addEnable">新增</a-button>
      <a-button type="success" :disabled="single" @click="handleUpdate" v-if="editEnable">修改</a-button>
      <a-button type="danger" :disabled="multiple" @click="handleDelete" v-if="removeEnable">删除</a-button>
      <a-button type="warning" @click="handleExport" v-if="exportEnable">导出</a-button>
      <a-button type="info" @click="handleJobLog" v-if="queryEnable">日志</a-button>
    </div>
    <s-table
      size="default"
      ref="table"
      rowKey="jobId"
      :rowSelection="{onChange: handleSelectionChange}"
      :columns="columns"
      :data="loadData"
      defaultSort="jobId">
      <span slot="serial" slot-scope="text, record, index">
        {{ index + 1 }}
      </span>
      <span slot="status" slot-scope="text, record">
        <a-switch
          :checked="record.status === '1'?true:false"
          checkedChildren="启用"
          unCheckedChildren="停用"
          @change="handleStatusChange(record)"
        ></a-switch>
      </span>
      <span slot="action" slot-scope="text, record">
        <a-button type="text" @click="handleRun(record)" v-if="editEnable">执行一次</a-button>
        <a-button type="text" @click="handleView(record)" v-if="queryEnable">详细</a-button>
      </span>
    </s-table>

    <!-- 添加或修改定时任务对话框 -->
    <a-modal :title="title" :visible="open" width="700px" :closable="false">
      <a-form-model ref="form" :model="form" :rules="rules" label-width="120px">
        <a-row>
          <a-col :span="12">
            <a-form-model-item label="任务名称" prop="jobName">
              <a-input v-model="form.jobName" placeholder="请输入任务名称" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="任务分组" prop="jobGroup">
              <a-select v-model="form.jobGroup" placeholder="请选择">
                <a-select-option
                  v-for="dict in jobGroupOptions"
                  :key="dict.dictValue"
                >{{ dict.dictLabel }}</a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item prop="invokeTarget">
              <span slot="label">
                调用方法
                <a-tooltip placement="top">
                  <div slot="content">
                    Bean调用示例：ryTask.ryParams('ry')
                    <br />Class类调用示例：com.ruoyi.quartz.task.RyTask.ryParams('ry')
                    <br />参数说明：支持字符串，布尔类型，长整型，浮点型，整型
                  </div>
                </a-tooltip>
              </span>
              <a-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="cron表达式" prop="cronExpression">
              <a-input v-model="form.cronExpression" placeholder="请输入cron执行表达式" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="是否并发" prop="concurrent">
              <a-radio-group v-model="form.concurrent">
                <a-radio-button label="0">允许</a-radio-button>
                <a-radio-button label="1">禁止</a-radio-button>
              </a-radio-group>
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="错误策略" prop="misfirePolicy">
              <a-radio-group :value="form.misfirePolicy">
                <a-radio-button label="1">立即执行</a-radio-button>
                <a-radio-button label="2">执行一次</a-radio-button>
                <a-radio-button label="3">放弃执行</a-radio-button>
              </a-radio-group>
            </a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="状态">
              <a-radio-group :value="form.status">
                <a-radio
                  v-for="dict in statusOptions"
                  :key="dict.dictValue"
                >{{ dict.dictLabel }}</a-radio>
              </a-radio-group>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
      <div slot="footer" class="dialog-footer">
        <a-button type="primary" @click="submitForm">确 定</a-button>
        <a-button @click="cancel">取 消</a-button>
      </div>
    </a-modal>

    <!-- 任务日志详细 -->
    <a-modal title="任务详细" :visible="openView" width="700px" :closable="false">
      <a-form-model ref="form" :model="form" label-width="120px" size="mini">
        <a-row>
          <a-col :span="12">
            <a-form-model-item label="任务编号：">{{ form.jobId }}</a-form-model-item>
            <a-form-model-item label="任务名称：">{{ form.jobName }}</a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="任务分组：">{{ jobGroupFormat(form) }}</a-form-model-item>
            <a-form-model-item label="创建时间：">{{ form.createTime }}</a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="cron表达式：">{{ form.cronExpression }}</a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="下次执行时间：">{{ parseTime(form.nextValidTime) }}</a-form-model-item>
          </a-col>
          <a-col :span="24">
            <a-form-model-item label="调用目标方法：">{{ form.invokeTarget }}</a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="任务状态：">
              <div v-if="form.status == 0">正常</div>
              <div v-else-if="form.status == 1">失败</div>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="是否并发：">
              <div v-if="form.concurrent == 0">允许</div>
              <div v-else-if="form.concurrent == 1">禁止</div>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="执行策略：">
              <div v-if="form.misfirePolicy == 0">默认策略</div>
              <div v-else-if="form.misfirePolicy == 1">立即执行</div>
              <div v-else-if="form.misfirePolicy == 2">执行一次</div>
              <div v-else-if="form.misfirePolicy == 3">放弃执行</div>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
      <template slot="footer">
        <a-button @click="openView = false">关 闭</a-button>
      </template>
    </a-modal>
  </a-card>
</template>

<script>
import { listJob, getJob, delJob, addJob, updateJob, exportJob, runJob, changeJobStatus } from '@/api/monitor/job'
import { checkPermi } from '@/utils/permissions'
import STable from '@/components/Table'

export default {
  name: 'Job',
  components: {
    STable
  },
  data () {
    return {
      // 遮罩层
      // loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 定时任务表格数据
      jobList: [],
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      // 是否显示详细弹出层
      openView: false,
      // 任务组名字典
      jobGroupOptions: [],
      // 状态字典
      statusOptions: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        jobName: undefined,
        jobGroup: undefined,
        status: undefined
      },
      // 表单参数
      form: {},
      columns: [
        {
          title: '序号',
          scopedSlots: { customRender: 'serial' }
        },
        {
          title: '任务编号',
          dataIndex: 'jobId'
        },
        {
          title: '任务名称',
          dataIndex: 'jobName'
        },
        {
          title: '任务组名',
          dataIndex: 'jobGroup'
        },
        {
          title: '调用目标字符串',
          dataIndex: 'invokeTarget'
        },
        {
          title: 'cron执行表达式',
          dataIndex: 'cronExpression'
        },
        {
          title: '状态',
          scopedSlots: { customRender: 'status' }
        },
        {
          title: '操作',
          width: '240px',
          dataIndex: 'action',
          scopedSlots: { customRender: 'action' }
        }
      ],
      // 表单校验
      rules: {
        jobName: [
          { required: true, message: '任务名称不能为空', trigger: 'blur' }
        ],
        invokeTarget: [
          { required: true, message: '调用目标字符串不能为空', trigger: 'blur' }
        ],
        cronExpression: [
          { required: true, message: 'cron执行表达式不能为空', trigger: 'blur' }
        ]
      },
      loadData: parameter => {
        return listJob(Object.assign(parameter, this.queryParams))
      },
      addEnable: checkPermi('monitor:job:add'),
      editEnable: checkPermi('monitor:job:edit'),
      removeEnable: checkPermi('monitor:job:remove'),
      exportEnable: checkPermi('monitor:job:export'),
      queryEnable: checkPermi('monitor:job:query')
    }
  },
  created () {
    this.getList()
    this.getDicts('sys_job_group').then(response => {
      this.jobGroupOptions = response.data
    })
    this.getDicts('sys_job_status').then(response => {
      this.statusOptions = response.data
    })
  },
  methods: {
    /** 查询定时任务列表 */
    getList () {
      // this.loading = true
      listJob(this.queryParams).then(response => {
        this.jobList = response.rows
        this.total = response.total
        // this.loading = false
      })
    },
    // 任务组名字典翻译
    jobGroupFormat (row, column) {
      return this.selectDictLabel(this.jobGroupOptions, row.jobGroup)
    },
    // 状态字典翻译
    statusFormat (row, column) {
      return this.selectDictLabel(this.statusOptions, row.status)
    },
    // 取消按钮
    cancel () {
      this.open = false
      this.reset()
    },
    // 表单重置
    reset () {
      this.form = {
        jobId: undefined,
        jobName: undefined,
        jobGroup: undefined,
        invokeTarget: undefined,
        cronExpression: undefined,
        misfirePolicy: 1,
        concurrent: 1,
        status: '0'
      }
      this.resetForm('form')
    },
    /** 搜索按钮操作 */
    handleQuery () {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery () {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 多选框选中数据
    handleSelectionChange (selectedRowKeys, selectedRows) {
      this.ids = selectedRows.map(item => item.jobId)
      this.single = selectedRows.length !== 1
      this.multiple = !selectedRows.length
    },
    // 任务状态修改
    handleStatusChange (row) {
      const text = row.status === '0' ? '启用' : '停用'
      const that = this
      this.$warning({
        title: '确认要"' + text + '""' + row.jobName + '"任务吗?',
        content: '',
        okText: '确认',
        cancelText: '取消',
        onOk () {
          row.status = row.status === '0' ? '1' : '0'
          changeJobStatus(row.jobId, row.status).then(res => {
            // this.msgSuccess()
            if (res.code === 200) {
              that.$notification.success({
                message: text + '成功'
              })
            } else {
              that.$notification.error({
                message: text + '失败'
              })
              row.status = row.status === '0' ? '1' : '0'
            }
          })
        },
        onCancel () {

        }
      })
      // this.$confirm('确认要"' + text + '""' + row.jobName + '"任务吗?', '警告', {
      //     confirmButtonText: '确定',
      //     cancelButtonText: '取消',
      //     type: 'warning'
      //   }).then(function () {
      //     return changeJobStatus(row.jobId, row.status)
      //   }).then(() => {
      //     this.msgSuccess(text + '成功')
      //   }).catch(function () {
      //     row.status = row.status === '0' ? '1' : '0'
      //   })
    },
    /* 立即执行一次 */
    handleRun (row) {
      const that = this
      this.$warning({
        title: '确认要立即执行一次"' + row.jobName + '"任务吗?',
        okText: '确定',
        cancelText: '取消',
        onOk () {
          runJob(row.jobId, row.jobGroup).then(res => {
            if (res.code === 200) {
              that.$notification.success({
                message: '执行成功'
              })
            } else {
              that.$notification.error({
                message: '执行失败'
              })
            }
          })
        }
      })
    },
    /** 任务详细信息 */
    handleView (row) {
      getJob(row.jobId).then(response => {
        this.form = response.data
        this.openView = true
      })
    },
    /** 任务日志列表查询 */
    handleJobLog () {
      this.$router.push('/job/log')
    },
    /** 新增按钮操作 */
    handleAdd () {
      this.reset()
      this.open = true
      this.title = '添加任务'
    },
    /** 修改按钮操作 */
    handleUpdate (row) {
      this.reset()
      console.log(this.ids)
      const jobId = row.jobId || this.ids
      getJob(jobId).then(response => {
        this.form = response.data
        this.open = true
        this.title = '修改任务'
      })
    },
    /** 提交按钮 */
    submitForm: function () {
      this.$refs.form.validate(valid => {
        if (valid) {
          if (this.form.jobId !== undefined) {
            updateJob(this.form).then(response => {
              if (response.code === 200) {
                this.msgSuccess('修改成功')
                this.open = false
                this.getList()
              }
            })
          } else {
            addJob(this.form).then(response => {
              if (response.code === 200) {
                this.msgSuccess('新增成功')
                this.open = false
                this.getList()
              }
            })
          }
        }
      })
    },
    /** 删除按钮操作 */
    handleDelete (row) {
      const jobIds = row.jobId || this.ids
      const that = this
      this.$warning({
        title: '是否确认删除定时任务编号为"' + jobIds + '"的数据项?',
        okText: '确定',
        cancelText: '取消',
        onOk () {
          delJob(jobIds).then(res => {
            if (res.code === 200) {
              that.$notification.success({
                message: '删除成功'
              })
            } else {
              that.$notification.error({
                message: '删除失败'
              })
            }
          })
        }
      })
    },
    /** 导出按钮操作 */
    handleExport () {
      const queryParams = this.queryParams
      const that = this
      this.$warning({
        title: '是否确认导出所有定时任务数据项?',
        okText: '确定',
        cancelText: '取消',
        onOk () {
          exportJob(queryParams).then(res => {
            if (res.code === 200) {
              that.download(res.msg)
            } else {
              that.$notification.error({
                message: '导出失败'
              })
            }
          })
        }
      })
    }
  }
}
</script>
